package org.jeecg.modules.online.cgform.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;

import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.enums.CgformEnum;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.online.cgform.entity.OnlCgformButton;
import org.jeecg.modules.online.cgform.entity.OnlCgformEnhanceJava;
import org.jeecg.modules.online.cgform.entity.OnlCgformEnhanceJs;
import org.jeecg.modules.online.cgform.entity.OnlCgformEnhanceSql;
import org.jeecg.modules.online.cgform.entity.OnlCgformHead;
import org.jeecg.modules.online.cgform.mapper.OnlCgformEnhanceJavaMapper;
import org.jeecg.modules.online.cgform.service.IOnlCgformEnhanceJavaService;
import org.jeecg.modules.online.cgform.service.IOnlCgformHeadService;
import org.jeecg.modules.online.cgform.util.SqlSymbolUtil;
import org.jeecg.modules.online.config.exception.DBException;
import org.jeecg.codegenerate.config.DbConfig;
import org.jeecg.codegenerate.database.DbReadTableUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController("onlCgformHeadController")
@RequestMapping({ "/online/cgform/head" })
@Slf4j
public class OnlCgformHeadController {
	@Autowired
	private IOnlCgformHeadService onlCgformHeadService;
	@Autowired
	private OnlCgformEnhanceJavaMapper onlCgformEnhanceJavaMapper;

	@Autowired
	private IOnlCgformEnhanceJavaService onlCgformEnhanceJavaService;

	private static final List<String> SYS_TABLE_PREFIX = Lists
			.newArrayList(new String[] { "act_", "ext_act_", "design_", "onl_", "sys_", "qrtz_", "cs_" });
	private static String SYNC_TABLES;

	@GetMapping({ "/list" })
	public Result<IPage<OnlCgformHead>> list(OnlCgformHead onlCgformHead,
			@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
			@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) {
		Result<IPage<OnlCgformHead>> result = new Result<>();
		QueryWrapper<OnlCgformHead> queryWrapper = QueryGenerator.initQueryWrapper(onlCgformHead,
				req.getParameterMap());
		Page<OnlCgformHead> page = new Page<>(pageNo, pageSize);
		IPage<OnlCgformHead> iPage = this.onlCgformHeadService.page(page, queryWrapper);
		if (onlCgformHead.getCopyType() != null && onlCgformHead.getCopyType() == 0) {
			this.onlCgformHeadService.initCopyState(iPage.getRecords());
		}

		result.setSuccess(true);
		result.setResult(iPage);
		return result;
	}

	@PostMapping({ "/add" })
	public Result<OnlCgformHead> add(@RequestBody OnlCgformHead onlCgformHead) {
		Result<OnlCgformHead> result = new Result<>();

		try {
			this.onlCgformHeadService.save(onlCgformHead);
			result.success("添加成功！");
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			result.error500("操作失败");
		}

		return result;
	}

	@PutMapping({ "/edit" })
	public Result<OnlCgformHead> edit(@RequestBody OnlCgformHead onlCgformH) {
		Result<OnlCgformHead> result = new Result<>();
		OnlCgformHead onlCgformHead = this.onlCgformHeadService.getById(onlCgformH.getId());
		if (onlCgformHead == null) {
			result.error500("未找到对应实体");
		} else {
			boolean status = this.onlCgformHeadService.updateById(onlCgformH);
			if (status) {
				result.success("修改成功!");
			}
		}

		return result;
	}

	@DeleteMapping({ "/delete" })
	public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
		try {
			this.onlCgformHeadService.deleteRecordAndTable(id);
		} catch (SQLException | DBException e) {
			return Result.error("删除失败" + e.getMessage());
		}

		return Result.OK("删除成功!", null);
	}

	@DeleteMapping({ "/removeRecord" })
	public Result<?> removeRecord(@RequestParam(name = "id", required = true) String id) {
		try {
			this.onlCgformHeadService.deleteRecord(id);
		} catch (SQLException | DBException e) {
			return Result.error("移除失败" + e.getMessage());
		}
		return Result.OK("移除成功!", null);
	}

	@DeleteMapping({ "/deleteBatch" })
	public Result<OnlCgformHead> deleteBatch(@RequestParam(name = "ids", required = true) String ids,
			@RequestParam(name = "flag") String flag) {
		Result<OnlCgformHead> result = new Result<>();
		if (ids != null && !"".equals(ids.trim())) {
			this.onlCgformHeadService.deleteBatch(ids, flag);
			result.success("删除成功!");
		} else {
			result.error500("参数不识别！");
		}

		return result;
	}

	@GetMapping({ "/queryById" })
	public Result<OnlCgformHead> queryById(@RequestParam(name = "id", required = true) String id) {
		Result<OnlCgformHead> result = new Result<>();
		OnlCgformHead onlCgformHead = (OnlCgformHead) this.onlCgformHeadService.getById(id);
		if (onlCgformHead == null) {
			result.error500("未找到对应实体");
		} else {
			result.setResult(onlCgformHead);
			result.setSuccess(true);
		}

		return result;
	}

	@GetMapping({ "/queryByTableNames" })
	public Result<?> queryByTableNames(@RequestParam(name = "tableNames", required = true) String tableNames) {
		LambdaQueryWrapper<OnlCgformHead> qw = new LambdaQueryWrapper<>();
		String[] tableNameArr = tableNames.split(",");
		qw.in(OnlCgformHead::getTableName, Arrays.asList(tableNameArr));
		List<OnlCgformHead> list = this.onlCgformHeadService.list(qw);
		return list == null ? Result.error("未找到对应实体") : Result.OK(list);
	}

	@PostMapping({ "/enhanceJs/{code}" })
	public Result<?> enhanceJs(@PathVariable("code") String code, @RequestBody OnlCgformEnhanceJs onlCgformEnhanceJs) {
		try {
			onlCgformEnhanceJs.setCgformHeadId(code);
			this.onlCgformHeadService.saveEnhance(onlCgformEnhanceJs);
			return Result.OK("保存成功!", null);
		} catch (Exception var4) {
			log.error(var4.getMessage(), var4);
			return Result.error("保存失败!");
		}
	}

	@GetMapping({ "/enhanceJs/{code}" })
	public Result<?> getEnhanceJs(@PathVariable("code") String code, HttpServletRequest request) {
		try {
			String type = request.getParameter("type");
			OnlCgformEnhanceJs onlCgformEnhanceJs = this.onlCgformHeadService.queryEnhance(code, type);
			return onlCgformEnhanceJs == null ? Result.error("查询为空") : Result.OK(onlCgformEnhanceJs);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return Result.error("查询失败!");
		}
	}

	@PutMapping({ "/enhanceJs/{code}" })
	public Result<?> getEnhanceJs(@PathVariable("code") String code,
			@RequestBody OnlCgformEnhanceJs onlCgformEnhanceJs) {
		try {
			onlCgformEnhanceJs.setCgformHeadId(code);
			this.onlCgformHeadService.editEnhance(onlCgformEnhanceJs);
			return Result.OK("保存成功!", null);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return Result.error("保存失败!");
		}
	}

	@GetMapping({ "/enhanceButton/{formId}" })
	public Result<?> enhanceButton(@PathVariable("formId") String enhanceButton, HttpServletRequest request) {
		try {
			List<OnlCgformButton> list = this.onlCgformHeadService.queryButtonList(enhanceButton);
			return list != null && list.size() != 0 ? Result.OK(list) : Result.error("查询为空");
		} catch (Exception var4) {
			log.error(var4.getMessage(), var4);
			return Result.error("查询失败!");
		}
	}

	@RequiresRoles({ "admin" })
	@PostMapping({ "/enhanceSql/{formId}" })
	public Result<?> postEnhanceSql(@PathVariable("formId") String formId,
			@RequestBody OnlCgformEnhanceSql onlCgformEnhanceSql) {
		try {
			onlCgformEnhanceSql.setCgformHeadId(formId);
			this.onlCgformHeadService.saveEnhance(onlCgformEnhanceSql);
			return Result.OK("保存成功!", null);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return Result.error("保存失败!");
		}
	}

	@GetMapping({ "/enhanceSql/{formId}" })
	public Result<?> getEnhanceSql(@PathVariable("formId") String formId, HttpServletRequest request) {
		try {
			String buttonCode = request.getParameter("buttonCode");
			OnlCgformEnhanceSql onlCgformEnhanceSql = this.onlCgformHeadService.queryEnhanceSql(formId, buttonCode);
			return onlCgformEnhanceSql == null ? Result.error("查询为空") : Result.OK(onlCgformEnhanceSql);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return Result.error("查询失败!");
		}
	}

	@RequiresRoles({ "admin" })
	@PutMapping({ "/enhanceSql/{formId}" })
	public Result<?> putEnhanceSql(@PathVariable("formId") String formId,
			@RequestBody OnlCgformEnhanceSql onlCgformEnhanceSql) {
		try {
			onlCgformEnhanceSql.setCgformHeadId(formId);
			this.onlCgformHeadService.editEnhance(onlCgformEnhanceSql);
			return Result.OK("保存成功!", null);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return Result.error("保存失败!");
		}
	}

	@PostMapping({ "/enhanceJava/{formId}" })
	public Result<?> postEnhanceJava(@PathVariable("formId") String formId,
			@RequestBody OnlCgformEnhanceJava onlCgformEnhanceJava) {
		try {
			if (!SqlSymbolUtil.isExistJava(onlCgformEnhanceJava)) {
				return Result.error("类实例化失败，请检查!");
			} else {
				onlCgformEnhanceJava.setCgformHeadId(formId);
				if (this.onlCgformHeadService.checkOnlyEnhance(onlCgformEnhanceJava)) {
					this.onlCgformHeadService.saveEnhance(onlCgformEnhanceJava);
					return Result.OK("保存成功!", null);
				} else {
					return Result.error("保存失败,数据不唯一!");
				}
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return Result.error("保存失败!");
		}
	}

	@GetMapping({ "/enhanceJava/{formId}" })
	public Result<?> getEnhanceJava(@PathVariable("formId") String formId, OnlCgformEnhanceJava var2) {
		try {
			var2.setCgformHeadId(formId);
			OnlCgformEnhanceJava var3 = this.onlCgformHeadService.queryEnhanceJava(var2);
			if (var3 == null) {
				var2.setCgJavaValue((String) null);
				return Result.OK(var2);
			} else {
				return Result.OK(var3);
			}
		} catch (Exception var4) {
			log.error(var4.getMessage(), var4);
			return Result.error("查询失败!");
		}
	}
	@PostMapping({"/deleteEnhanceJavaByButtonCode/{formId}"})
	public Result<?> deleteEnhanceJavaByButtonCode(@PathVariable("formId") String formId, @RequestBody OnlCgformEnhanceJava onlCgformEnhanceJava){
		LambdaQueryWrapper<OnlCgformEnhanceJava> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(OnlCgformEnhanceJava::getButtonCode, onlCgformEnhanceJava.getButtonCode());
		queryWrapper.eq(OnlCgformEnhanceJava::getCgformHeadId, formId);
		onlCgformEnhanceJavaService.remove(queryWrapper);

		return Result.OK("删除成功!");
	}

	@GetMapping({ "/enhanceJavaByButtonCode/{formId}" })
	public Result<?> getEnhanceJavaByButtonCode(@PathVariable("formId") String var1, OnlCgformEnhanceJava var2) {
		try {
			LambdaQueryWrapper<OnlCgformEnhanceJava> var3 = new LambdaQueryWrapper<>();
			var3.eq(OnlCgformEnhanceJava::getButtonCode, var2.getButtonCode());
			var3.eq(OnlCgformEnhanceJava::getCgformHeadId, var1);
			OnlCgformEnhanceJava var4 = (OnlCgformEnhanceJava) this.onlCgformEnhanceJavaMapper.selectOne(var3);
			if (var4 == null) {
				return Result.error("查询为空");
			} else {
				log.info("---------enhanceJavaByButtonCode-----------" + var4.toString());
				return Result.OK(var4);
			}
		} catch (Exception var5) {
			log.error(var5.getMessage(), var5);
			return Result.error("查询失败!");
		}
	}

	@PutMapping({ "/enhanceJava/{formId}" })
	public Result<?> putEnhanceJava(@PathVariable("formId") String var1, @RequestBody OnlCgformEnhanceJava var2) {
		try {
			if (!SqlSymbolUtil.isExistJava(var2)) {
				return Result.error("类实例化失败，请检查!");
			} else {
				var2.setCgformHeadId(var1);
				if (this.onlCgformHeadService.checkOnlyEnhance(var2)) {
					this.onlCgformHeadService.editEnhance(var2);
					return Result.OK("保存成功!", null);
				} else {
					return Result.error("保存失败,数据不唯一!");
				}
			}
		} catch (Exception var4) {
			log.error(var4.getMessage(), var4);
			return Result.error("保存失败!");
		}
	}

	@GetMapping({ "/queryTables" })
	public Result<?> queryTables(HttpServletRequest request) {
		String username = JwtUtil.getUserNameByToken(request);
		if (!"admin".equals(username)) {
			return Result.error("noadminauth");
		} else {
			List<String> tables;
			try {
				tables = DbReadTableUtil.getTables();
			} catch (SQLException e) {
				log.error(e.getMessage(), e);
				return Result.error("同步失败，未获取数据库表信息");
			}

			SqlSymbolUtil.sortByStr(tables);
			List<String> queryTables = this.onlCgformHeadService.queryOnlinetables();
			tables.removeAll(queryTables);
			List<Map<String, String>> result = new ArrayList<>();
			Iterator<String> iterator = tables.iterator();

			while (iterator.hasNext()) {
				String tablename = iterator.next();
				if (!isSystemTable(tablename)) {
					Map<String, String> map = new HashMap<>();
					map.put("id", tablename);
					result.add(map);
				}
			}

			return Result.OK(result);
		}
	}

	@PostMapping({ "/transTables/{tbnames}" })
	@RequiresRoles({ "admin" })
	public Result<?> transTables(@PathVariable("tbnames") String tbnames, HttpServletRequest request) {
		String username = JwtUtil.getUserNameByToken(request);
		if (!"admin".equals(username)) {
			return Result.error("noadminauth");
		} else if (oConvertUtils.isEmpty(tbnames)) {
			return Result.error("未识别的表名信息");
		} else if (SYNC_TABLES != null && SYNC_TABLES.equals(tbnames)) {
			return Result.error("不允许重复生成!");
		} else {
			SYNC_TABLES = tbnames;
			String[] tbnamesArr = tbnames.split(",");

			for (int i = 0; i < tbnamesArr.length; ++i) {
				if (oConvertUtils.isNotEmpty(tbnamesArr[i])) {
					int count = this.onlCgformHeadService.count(
							(new LambdaQueryWrapper<OnlCgformHead>()).eq(OnlCgformHead::getTableName, tbnamesArr[i]));
					if (count <= 0) {
						log.info("[IP] [online数据库导入表]   --表名：" + tbnamesArr[i]);
						this.onlCgformHeadService.saveDbTable2Online(tbnamesArr[i]);
					}
				}
			}

			SYNC_TABLES = null;
			return Result.OK("同步完成!", null);
		}
	}

	@GetMapping({ "/rootFile" })
	public Result<?> rootFile() {
		JSONArray jsonArr = new JSONArray();
		File[] listRoots = File.listRoots();
		File[] files = listRoots;
		int listRootsSize = listRoots.length;

		for (int i = 0; i < listRootsSize; ++i) {
			File file = files[i];
			JSONObject jsonObj = new JSONObject();
			if (file.isDirectory()) {
				System.out.println(file.getPath());
				jsonObj.put("key", file.getAbsolutePath());
				jsonObj.put("title", file.getPath());
				jsonObj.put("opened", false);
				JSONObject jsonObj2 = new JSONObject();
				jsonObj2.put("icon", "custom");
				jsonObj.put("scopedSlots", jsonObj2);
				jsonObj.put("isLeaf", file.listFiles() == null || file.listFiles().length == 0);
			}

			jsonArr.add(jsonObj);
		}

		return Result.OK(jsonArr);
	}

	@GetMapping({ "/fileTree" })
	public Result<?> fileTree(@RequestParam(name = "parentPath", required = true) String parentPath) {
		JSONArray jsonArr = new JSONArray();
		File var3 = new File(parentPath);
		File[] var4 = var3.listFiles();
		File[] var5 = var4;
		int var6 = var4.length;

		for (int var7 = 0; var7 < var6; ++var7) {
			File var8 = var5[var7];
			if (var8.isDirectory() && oConvertUtils.isNotEmpty(var8.getPath())) {
				JSONObject var9 = new JSONObject();
				System.out.println(var8.getPath());
				var9.put("key", var8.getAbsolutePath());
				var9.put("title", var8.getPath().substring(var8.getPath().lastIndexOf(File.separator) + 1));
				var9.put("isLeaf", var8.listFiles() == null || var8.listFiles().length == 0);
				var9.put("opened", false);
				JSONObject var10 = new JSONObject();
				var10.put("icon", "custom");
				var9.put("scopedSlots", var10);
				jsonArr.add(var9);
			}
		}

		return Result.OK(jsonArr);
	}

	@GetMapping({ "/tableInfo" })
	public Result<?> tableInfo(@RequestParam(name = "code", required = true) String code) {
		OnlCgformHead head = this.onlCgformHeadService.getById(code);
		if (head == null) {
			return Result.error("未找到对应实体");
		} else {
			Map<String, Object> data = new HashMap<>();
			data.put("main", head);
			if (head.getTableType() == 2) {
				String var4 = head.getSubTableStr();
				if (oConvertUtils.isNotEmpty(var4)) {
					List<OnlCgformHead> var5 = new ArrayList<>();
					String[] var6 = var4.split(",");
					String[] var7 = var6;
					int var8 = var6.length;

					for (int var9 = 0; var9 < var8; ++var9) {
						String var10 = var7[var9];
						LambdaQueryWrapper<OnlCgformHead> var11 = new LambdaQueryWrapper<>();
						var11.eq(OnlCgformHead::getTableName, var10);
						OnlCgformHead var12 = (OnlCgformHead) this.onlCgformHeadService.getOne(var11);
						var5.add(var12);
					}

					Collections.sort(var5, new Comparator<OnlCgformHead>() {
						public int compare(OnlCgformHead var1, OnlCgformHead var2) {
							Integer var3 = var1.getTabOrderNum();
							if (var3 == null) {
								var3 = 0;
							}

							Integer var4 = var2.getTabOrderNum();
							if (var4 == null) {
								var4 = 0;
							}

							return var3.compareTo(var4);
						}
					});
					data.put("sub", var5);
				}
			}

			Integer var13 = head.getTableType();
			if ("Y".equals(head.getIsTree())) {
				var13 = 3;
			}

			List<Map<String, Object>> jspModelList = CgformEnum.getJspModelList(var13);
			data.put("jspModeList", jspModelList);
			data.put("projectPath", DbConfig.getProjectPath());
			return Result.OK(data);
		}
	}

	@PostMapping({ "/copyOnline" })
	public Result<?> copyOnline(@RequestParam(name = "code", required = true) String code) {
		try {
			OnlCgformHead head = this.onlCgformHeadService.getById(code);
			if (head == null) {
				return Result.error("未找到对应实体");
			}

			this.onlCgformHeadService.copyOnlineTableConfig(head);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return Result.OK();
	}

	private boolean isSystemTable(String tablename) {
		Iterator<String> iterator = SYS_TABLE_PREFIX.iterator();

		String prefix;
		do {
			if (!iterator.hasNext()) {
				return false;
			}

			prefix = iterator.next();
		} while (!tablename.startsWith(prefix) && !tablename.startsWith(prefix.toUpperCase()));

		return true;
	}
}
